package com.tool.cn.mybaties;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.mybatis.generator.api.ShellRunner;

import com.tool.cn.use.PropUse;
import com.tool.cn.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 
 * @author wangzonghui
 * @date 2020年6月23日 上午10:48:02 
 * @Description:给予mybaties和frameker生成mapping（xml）、model、dao、service、action类
 */
public class CreateAllObject {
	
	static String rootUrl="./template";
	
	@SuppressWarnings("static-access")
	public static void main(String[] args) throws ClassNotFoundException {
		//升级mapping生成位置
		ShellRunner shell=new ShellRunner();
		String xml=System.getProperty("user.dir")+"\\template\\generator.xml";
		args=new String[]{"-configfile",xml,"-overwrite"};
		shell.main(args);
		
		
		//TODO 增加action、server类生成，目录必须为action、service、dao同级
		String proper=System.getProperty("user.dir")+"\\src\\com\\tool\\cn\\init.properties";
		PropUse propUtil=new PropUse();
		propUtil.loadFile(proper);
		
		
		boolean isHas = false;
		final String classAuthor = "wangzonghui"; // 作者姓名
		String functionName = "主机信息类"; // 功能描述
		
		// 通过model类获取路径信息
		// 目录生成结构：{packageName}/{moduleName}/{dao,service,action}/{className}
		String classPathPackPath = propUtil.getStringValue("model"); // com.javaosc.user.model
		String path = classPathPackPath.substring(0, classPathPackPath.lastIndexOf(".")); // com.javaosc.user
		String packageName = path.substring(0, path.lastIndexOf("."));// com.javaosc
		String moduleName = path.substring(path.lastIndexOf(".") + 1);// user
		String className = propUtil.getStringValue("className");// role

		if (StringUtil.isEmpty(packageName) || StringUtil.isEmpty(moduleName) || StringUtil.isEmpty(className) || StringUtil.isEmpty(functionName)) {
			System.out.println("参数设置错误：包名、模块名、类名、功能名不能为空。");
			return;
		}
		System.out.println("=========== 包解析如下 ===========");
		System.out.println("path: " + path);
		System.out.println("packageName: " + packageName);
		System.out.println("moduleName: " + moduleName);
		System.out.println("className:" + className);
		System.out.println("=========== 解析完毕  ===========");

		// 获取类路径
		String classPath= propUtil.getStringValue("project")+File.separator+classPathPackPath.replace(".", File.separator)+File.separator;
		
		// 定义模板变量
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("packageName", StringUtils.lowerCase(packageName));
		param.put("moduleName", StringUtils.lowerCase(moduleName));
		param.put("uncapitalizeName", StringUtils.uncapitalize(className)); //首字母小写
		param.put("capitalizeName", StringUtils.capitalize(className)); //首字母大写
		param.put("author", StringUtils.isNotBlank(classAuthor) ? classAuthor : "wangzonghui");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置格式化格式
		String nowDate = sdf.format(new Date());
		param.put("date", nowDate);// 当前时间
		param.put("functionName", functionName);

		boolean flag = false;
		// 生成 Service 接口
		String filePath = classPath.replace("model", "service") + param.get("capitalizeName") + "Service.java";
		String servicePath = filePath;
		
		File outFile = new File(servicePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = createFile(param, "service-mapper.ftl", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + servicePath);
			} else {
				System.out.println(param.get("capitalizeName") + "Service.java 创建失败!");
			}
		}

		// 生成 ServiceImpl 接口实现类
		filePath = classPath.replace("model", "service") + param.get("capitalizeName") + "ServiceImpl.java";
		outFile = new File(filePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = createFile(param, "serviceImpl-mapper.ftl", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + filePath);
			} else {
				System.out.println(param.get("capitalizeName") + "ServiceImpl.java 创建失败!");
			}
		}

		// 生成 Action
		filePath = classPath.replace("model", "action") + param.get("capitalizeName") + "Action.java";
		String actionPath = filePath;
		
		outFile = new File(actionPath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = createFile(param, "action-mapper.ftl", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + actionPath);
			} else {
				System.out.println(param.get("capitalizeName") + "Action.java 创建失败!");
			}
		}

		if (!isHas && flag) {
			System.out.println("提示：模块创建完毕，请验证！");
		} else {
			System.out.println("提示：为防止生成覆盖，已生成的文件不做处理，若要重新生成，请删除原来的文件(注意代码备份！)");
		}

	}
	
	
	public static boolean createFile(Map<String, Object> param, String templateFile, File outFile){
		Configuration cfg=new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
		
		try {
			if(!outFile.getParentFile().exists()){
				outFile.getParentFile().mkdirs();
			}
			
			cfg.setDirectoryForTemplateLoading(new File(rootUrl));
			Template template=cfg.getTemplate(templateFile);
			
			Writer javaWriter = new FileWriter(outFile);
			template.process(param, javaWriter);
			javaWriter.flush();
			javaWriter.close();
			
			
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} catch (TemplateException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

}
